package com.alameda.common.config.spy;

import com.alameda.common.base.constant.SpyConstant;
import com.p6spy.engine.common.P6Util;
import com.p6spy.engine.spy.appender.MessageFormattingStrategy;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * P6spy配置类 设置自定义控制台打印完整Sql日志格式
 *
 * @author Lv
 * @date 2024/2/19
 */
public class P6spySqlLogConfig implements MessageFormattingStrategy {
    /**
     * 自定义Sql日志
     *
     * @param connectionId 连接id
     * @param now          当前时间
     * @param elapsed      耗时多久
     * @param category     类别
     * @param prepared     mybatis带占位符的sql
     * @param sql          占位符换成参数的sql
     * @param url          sql连接的 url
     * @return
     */
    @Override
    public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {
        return !"".equals(sql.trim()) ? new SimpleDateFormat(SpyConstant.DATE_FORMAT).format(new Date()) + " | took " + elapsed + "ms | " + category
                + " | connection " + connectionId + formatSql(P6Util.singleLine(SpyConstant.SPACE + sql)) + ";" + SpyConstant.NEW_LINE : "";
    }

    /**
     * 格式化SQL
     *
     * @param sql DML语句
     * @return 格式化过后的Sql
     */
    @SuppressWarnings("all")
    private String formatSql(String sql) {
        // 处理占位符
        String sqlString = sql
                .replaceAll(SpyConstant.SPACE_XML, SpyConstant.SPACE)
                .replaceAll(SpyConstant.NULL_LINE, SpyConstant.SPACE);

        // 处理小写关键字
        String sqlLowerCase = sqlString
                .replaceAll(SpyConstant.SELECT_LOWERCASE, SpyConstant.NEW_LINE + SpyConstant.SELECT_LOWERCASE + SpyConstant.NEW_LINE)
                .replaceAll(SpyConstant.FROM_LOWERCASE, SpyConstant.NEW_LINE + SpyConstant.FROM_LOWERCASE + SpyConstant.NEW_LINE)
                .replaceAll(SpyConstant.WHERE_LOWERCASE, SpyConstant.NEW_LINE + SpyConstant.WHERE_LOWERCASE + SpyConstant.NEW_LINE)
                .replaceAll(SpyConstant.ORDER_LOWERCASE, SpyConstant.NEW_LINE + SpyConstant.ORDER_LOWERCASE)
                .replaceAll(SpyConstant.GROUP_LOWERCASE, SpyConstant.NEW_LINE + SpyConstant.GROUP_LOWERCASE)
                .replaceAll(SpyConstant.UNION_LOWERCASE, SpyConstant.NEW_LINE + SpyConstant.UNION_LOWERCASE)
                .replaceAll(SpyConstant.INSERT_LOWERCASE, SpyConstant.NEW_LINE + SpyConstant.INSERT_LOWERCASE)
                .replaceAll(SpyConstant.INTO_LOWERCASE, SpyConstant.INTO_LOWERCASE + SpyConstant.NEW_LINE)
                .replaceAll(SpyConstant.VALUES_LOWERCASE, SpyConstant.NEW_LINE + SpyConstant.VALUES_LOWERCASE + SpyConstant.NEW_LINE)
                .replaceAll(SpyConstant.UPDATE_LOWERCASE, SpyConstant.NEW_LINE + SpyConstant.UPDATE_LOWERCASE + SpyConstant.NEW_LINE)
                .replaceAll(SpyConstant.SET_LOWERCASE, SpyConstant.NEW_LINE + SpyConstant.SET_LOWERCASE + SpyConstant.NEW_LINE)
                .replaceAll(SpyConstant.DELETE_LOWERCASE, SpyConstant.NEW_LINE + SpyConstant.DELETE_LOWERCASE);

        // 处理大写关键字
        String sqlUpperCase = sqlLowerCase
                .replaceAll(SpyConstant.DELETE_UPPERCASE, SpyConstant.NEW_LINE + SpyConstant.DELETE_LOWERCASE)
                .replaceAll(SpyConstant.SELECT_UPPERCASE, SpyConstant.NEW_LINE + SpyConstant.SELECT_LOWERCASE + SpyConstant.NEW_LINE)
                .replaceAll(SpyConstant.FROM_UPPERCASE, SpyConstant.NEW_LINE + SpyConstant.FROM_LOWERCASE + SpyConstant.NEW_LINE)
                .replaceAll(SpyConstant.WHERE_UPPERCASE, SpyConstant.NEW_LINE + SpyConstant.WHERE_LOWERCASE + SpyConstant.NEW_LINE)
                .replaceAll(SpyConstant.ORDER_UPPERCASE, SpyConstant.NEW_LINE + SpyConstant.ORDER_LOWERCASE)
                .replaceAll(SpyConstant.GROUP_UPPERCASE, SpyConstant.NEW_LINE + SpyConstant.GROUP_LOWERCASE)
                .replaceAll(SpyConstant.UNION_UPPERCASE, SpyConstant.NEW_LINE + SpyConstant.UNION_LOWERCASE)
                .replaceAll(SpyConstant.INSERT_UPPERCASE, SpyConstant.NEW_LINE + SpyConstant.INSERT_LOWERCASE)
                .replaceAll(SpyConstant.INTO_UPPERCASE, SpyConstant.INTO_LOWERCASE + SpyConstant.NEW_LINE)
                .replaceAll(SpyConstant.VALUES_UPPERCASE, SpyConstant.NEW_LINE + SpyConstant.VALUES_LOWERCASE + SpyConstant.NEW_LINE)
                .replaceAll(SpyConstant.UPDATE_UPPERCASE, SpyConstant.NEW_LINE + SpyConstant.UPDATE_LOWERCASE + SpyConstant.NEW_LINE)
                .replaceAll(SpyConstant.SET_UPPERCASE, SpyConstant.NEW_LINE + SpyConstant.SET_LOWERCASE + SpyConstant.NEW_LINE);

        return sqlUpperCase;
    }
}